using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace YYJ.UI {
    public partial class BaseForm : Form {
        public BaseForm() {
            InitializeComponent();
        }
        
        protected T switchTo<T>() where T : BaseForm {
            if( _cache == null ) {
                _cache = new Dictionary<string, BaseForm>();
            }
            string fullName = typeof( T ).FullName;
            BaseForm frmNew;
            if( !_cache.TryGetValue( fullName, out frmNew ) ) {
                frmNew = Activator.CreateInstance<T>();
                // all forms share the same cache
                frmNew._cache = this._cache; 
                // close the previous form when itself is closed
                // it would make a closing-chain to all forms
                frmNew.FormClosed += delegate { this.Close(); };

                _cache.Add( fullName, frmNew );
            }
            if( frmNew != null ) {
                frmNew.Location = this.Location;
                frmNew.StartPosition = FormStartPosition.Manual;
                frmNew.Show();
                this.Hide();
            }
            return frmNew as T;
        }

        protected Dictionary<string, BaseForm> _cache = null;

        protected void displayLabelForAWhile( Label lbl, int duration ) {
            lbl.Visible = true;
            System.Timers.Timer t = new System.Timers.Timer( duration );
            t.Elapsed += delegate {
                Thread thd = new Thread( new ParameterizedThreadStart( this.hideLabelThreadSafe ) );
                thd.Start( lbl );
                t.Stop();
            };
            t.Start();
        }

        //http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx
        private delegate void HideLabelCallback( Label lbl );
        private void hideLabelThreadSafe( Object objLabel ) {
            Label lbl = objLabel as Label;
            if( lbl.InvokeRequired ) {
                HideLabelCallback d = new HideLabelCallback( hideLabelThreadSafe );
                this.Invoke( d, new object[] { lbl } );
            } else {
                lbl.Visible = false;
            }
        }
    }
}